package com.zzyl.service.impl;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.service.WeChatService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * 微信小程序登录流程 接口实现类 --- 封装获取openid、access_token、phone方法
 */

@Slf4j
@Service
public class WeChatServiceImpl implements WeChatService {

    //读取配置文件中的测试id和secret
    @Value("${zzyl.wechat.appid}")
    private String appid;
    @Value("${zzyl.wechat.secret}")
    private String secret;

    /* 微信接口地址（微信小程序开发官网提供）*/
    //登录
    private String openid_url = "https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code";
    //获取 Token
    private String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET";
    //获取手机号
    private String phone_url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=ACCESS_TOKEN";


    /**
     * 获取 openid
     * @param code  登录凭证
     * @return openid
     */
    @Override
    public String getOpenid(String code) {

        try {
            //将提供的请求数据模板中的 appid、secret、code 替换为真实用户的
            String openid_url_temp = openid_url.replace("APPID", appid)
                                               .replace("SECRET", secret)
                                               .replace("JSCODE", code);

            //使用 HuTool 发送 GET 请求，得到响应结果
            String result = HttpUtil.get(openid_url_temp);
            /*
                result:{"openid":"xxxxxx","session_key":"xxxxx","unionid":"xxxxx","errcode":0,"errmsg":"xxxxx"}
            */

            //记录日志
            log.info("获取微信openId的结果为：{}",result);

            //字符串解析为JSON
            JSONObject jsonObject = JSONUtil.parseObj(result);
            /*
                jsonObject:
                            {
                            "openid":"xxxxxx",
                            "session_key":"xxxxx",
                            "unionid":"xxxxx",
                            "errcode":0,
                            "errmsg":"xxxxx"
                            }
             */

            //响应结果中含有错误信息字样：抛出异常，无错误信息：返回openid
            if (jsonObject.get("error_code")!=null){
                throw new BaseException(BasicEnum.GET_OPENID_ERROR);
            }
            return jsonObject.getStr("openid");

        }catch (Exception e){

            throw new BaseException(BasicEnum.GET_OPENID_ERROR);

        }

    }

    /**
     * 获取 phone 手机号 【微信官方接口规定须先获取 access_token】
     * @param code  手机号凭证
     * @return 手机号
     */
    @Override
    public String getPhone(String code) {

        try {
            /* 1、获取 access_token */

            //将提供的请求数据模板中的 appid、secret 替换为真实用户的
            String access_token_url_temp = access_token_url.replace("APPID", appid)
                                                           .replace("SECRET", secret);

            //使用 HuTool 发送 GET 请求，得到响应结果
            String result = HttpUtil.get(access_token_url_temp);

            //记录日志
            log.info("获取微信access_token的结果为：{}",result);

            //字符串解析为JSON
            JSONObject jsonObject = JSONUtil.parseObj(result);
            /*
                jsonObject：
                            {
                            "access_token":"ACCESS_TOKEN",
                            "expires_in":7200
                            }
             */

            //响应结果中含有错误信息字样：抛出异常，无错误信息：拿到 access_token
            if (jsonObject.get("error_code")!=null){
                throw new BaseException(BasicEnum.GET_OPENID_ERROR);
            }
            String accessToken = jsonObject.getStr("access_token");


            /* 2、获取手机号 phone */

            //将提供的请求数据模板中的 ACCESS_TOKEN 替换为真实用户的
            String phone_url_temp = phone_url.replace("ACCESS_TOKEN", accessToken);

            //使用MAP封装code => "code":"xxx"
            Map<String, String> map = new HashMap<>();
            map.put("code",code);

            //使用 HuTool 发送 POST 请求，得到响应结果
            result = HttpUtil.post(phone_url_temp,JSONUtil.toJsonStr(map));

            //记录日志
            log.info("获取微信绑定的手机号的响应结果为：{}",result);

            //字符串解析为JSON
            jsonObject = JSONUtil.parseObj(result);

            //响应结果中的errcode字段不为0：抛出异常，为0：无错误信息，返回 【微信开发官网规定】
            if (jsonObject.getInt("errcode") != 0){
                throw new BaseException(BasicEnum.GET_PHONE_ERROR);
            }
            return jsonObject.getJSONObject("phone_info").getStr("phoneNumber");

        }catch (Exception e){

            throw new BaseException(BasicEnum.GET_PHONE_ERROR);

        }

    }




}
